#include "Sender.h"
#include "utils.hpp"

using namespace sw::redis;

class NullSender : public Sender
{
public:
	bool Send(const cv::Mat& frame, const std::string& taskId, int number) {
		return true;
	}
};

class RedisSender : public Sender
{
public:
	explicit RedisSender(const std::string& uri, const std::string& key)
		: redis(uri), rootKey(key) {}
	bool Send(const cv::Mat& frame, const std::string& taskId, int number);

private:
	sw::redis::Redis redis;
	std::string rootKey;
	std::string currentTaskId;
};

bool RedisSender::Send(const cv::Mat& frame, const std::string& taskId, int number)
{
	std::vector<uchar> buf;
	std::vector<char> data;
	cv::imencode(".jpg", frame, buf);
	base64_encode(buf, data);

	if (currentTaskId != taskId) {
		redis.rpush(rootKey, taskId);
		currentTaskId = taskId;
	}
	
	char keybuf[2048];
	sprintf(keybuf, "%s-%04d", taskId.c_str(), number);
	std::string imagKey(keybuf);
	redis.set(imagKey, std::string(data.begin(), data.end()));
	redis.rpush(taskId, imagKey);
	
	return true;
}

std::shared_ptr<Sender> Sender::Create(const std::string& uri, const std::string& arg, int type)
{
	if (uri.empty()) {
		return std::make_shared<NullSender>();
	} else if (type == 0) {
		return std::make_shared<RedisSender>(uri, arg);
	}
	return nullptr;
}
